using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using System.IO;
using DevExpress.XtraTreeList.Nodes;

namespace ProgNetComponentsDx.Controls.Editors
{
    public partial class OpenFolderDlg : DevExpress.XtraEditors.XtraForm
    {
        private string _RootName;


        public string SelectedPath { get; set; }
        
        public string RootDir { get; set; }
        public string RootName
        {
            get
            {
                if (_RootName.IsNull())
                    _RootName = "ROOT";
                return _RootName;
            }
            set
            {
                _RootName = value;
                lblRootName.Text = RootName + ":";
            }
        }
        public string Description
        {
            get { return Text; }
            set { Text = value; }
        }

        public bool ShowNewFolderButton { get; set; }
        public OpenFolderDlg()
        {
            InitializeComponent();
        }

        private void OpenFolderDlg_Load(object sender, EventArgs e)
        {
            lblRootName.Text = RootName + ":";
            lblRoot.Text = RootDir;

            treeList1.Nodes.Clear();
            if (RootDir.IsNull())
                InitDrives();
            else
            {
                TreeListNode n = treeList1.AppendNode(new object[] { RootDir, new DirectoryInfo(RootDir).Name }, null);
                n.Tag = true;
                n.HasChildren = DirHasChildren(RootDir);
            }
            if (SelectedPath.IsNotNull())
                SelectDir(SelectedPath);
            else
                SelectDir(RootDir);
        }
        
        private void InitDrives()
        {
            TreeListNode node;
            try
            {
                string[] root = Directory.GetLogicalDrives();
                foreach (string s in root)
                {
                    node = treeList1.AppendNode(new object[] { s, s }, null);
                    System.IO.DriveInfo di = new System.IO.DriveInfo(s);
                    if (di.IsReady)
                    {
                        node.HasChildren = DirHasChildren(s);
                    }
                    node.Tag = true;
                }
            }
            catch { }
        }
        private void InitFolders(TreeListNode node)
        {
            if (this.InvokeRequired)
            {
                    this.Invoke(new Action<TreeListNode>(this.InitFolders), node);
            }
            else
            {
                try
                {
                    treeList1.LockReloadNodes();
                    string[] dirs = Directory.GetDirectories(node[this.colPath].AsString(), "*", SearchOption.TopDirectoryOnly);
                    {
                        foreach (string d in dirs)
                        {
                            try
                            {
                                TreeListNode n = treeList1.AppendNode(new object[] { d, d.Substring(d.LastIndexOf(Path.DirectorySeparatorChar)).TrimStartEnd('\\') }, node);
                                n.Tag = true;
                                n.HasChildren = DirHasChildren(d);
                            }
                            catch { }
                        }
                    }
                }
                catch { }
                finally
                {
                    treeList1.UnlockReloadNodes();
                }
            }
        }
        private bool DirHasChildren(string path)
        {
            bool result = false;
            try
            {
                string[] dirs = Directory.GetDirectories(path, "*", SearchOption.TopDirectoryOnly);
                result = dirs != null && dirs.Length > 0;
            }
            catch { result = false; }
            return result;
        }
        private void treeList1_BeforeExpand(object sender, DevExpress.XtraTreeList.BeforeExpandEventArgs e)
        {
            if (e.Node.Tag.IsNotNull())
            {
                backgroundWorker1.RunWorkerAsync(e.Node);
                e.Node.Tag = null;
            }
        }
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            TreeListNode n = e.Argument as TreeListNode;
            InitFolders(n);
        }
        private void SelectDir(string dir)
        {
            treeList1.Focus();
            if (dir.IsNotNull())
            {
                foreach (TreeListNode n in treeList1.Nodes)
                {
                    TreeListNode node = FindNode(n, dir);
                    if (node != null)
                    {
                        treeList1.FocusedNode = node;
                        break;
                    }
                }
            }
        }

        private TreeListNode FindNode(TreeListNode node, string path)
        {
            TreeListNode n = null;
            if (node != null)
            {
                if (node[this.colPath].AsString().ToUpper() ==
                    path.ToUpper())
                    return node;
                if (!path.ToUpper().StartsWith(node[this.colPath].AsString().ToUpper()))
                    return null;
                else
                    n = node;
                if (node.Tag.IsNotNull())
                {
                    InitFolders(node);
                    node.Tag = null;
                }
                foreach (TreeListNode n1 in node.Nodes)
                {
                    TreeListNode n2 = FindNode(n1, path);
                    if (n2 != null)
                    {
                        n = n2;
                        break;
                    }
                }
            }
            return n;
        }
        private void btnOk_Click(object sender, EventArgs e)
        {
            SelectedPath = treeList1.FocusedNode[colPath].AsString();
            DialogResult = DialogResult.OK;
            Close();
        }
        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            Close();
        }

        private void treeList1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Right)
            {
                if (treeList1.FocusedNode != null)
                {
                    if (treeList1.FocusedNode.Tag.IsNotNull())
                    {
                        InitFolders(treeList1.FocusedNode);
                        treeList1.FocusedNode.Tag = null;
                    }
                    treeList1.FocusedNode.Expanded = true;
                    if (treeList1.FocusedNode.HasChildren)
                        treeList1.FocusedNode = treeList1.FocusedNode.FirstNode;
                }
            }
            if (e.KeyCode == Keys.Left)
            {
                if (treeList1.FocusedNode != null)
                {
                    treeList1.FocusedNode = treeList1.FocusedNode.ParentNode;
                    if (treeList1.FocusedNode != null)
                        treeList1.FocusedNode.Expanded = false;
                }
            }
            if (e.KeyCode == Keys.Enter)
            {
                btnOk.PerformClick();
            }
        }
    }
}